<?php
/**
 *Import, tag songs
 */
 
class Song
{
  private $id;
  private $usr_id;
  private $path;
  private $format;
  private $bitrate;
  private $filesize;
  private $playtime;
  private $stamp;
  private $rating;
  private $downloads;
  private $title;
  private $artist;
  private $album;
  private $genre;
  private $comment;
  private $year;
  private $number;
  private $label;
  private $tags;
  
  private $fields = array(
    'id','usr_id','path','format','bitrate','filesize','playtime','stamp',
    'rating','downloads','title','artist','album','genre','comment','year',
    'number','label','tags'
  );
  private $entity_fields = array(
    'artist','title','album','genre','comment'
  );
  
  public function __construct($id,$values = '')
  {
    if(!empty($id) and empty($values))//db lookup
    {
      $this->id = $id;
      $this->read();
    }
  }
  
  public function read()
  {
    $sql = "SELECT * FROM song WHERE id='".$this->id."' LIMIT 1";
    $dbh = new dbSql();
    $res = $dbh->query($sql);
    if(!empty($res))
    {
      foreach($res[0] as $label=>$value)
      {
        $this->$label = $value;
      }
    }
  }

  public function getFileSize()
  {
    return $this->filesize;
  }
  public function getId()
  {
    return $this->id;
  }
  public function getLabel()
  {
    $artist = utf8_encode(html_entity_decode($this->artist,ENT_QUOTES));
    $title  = utf8_encode(html_entity_decode($this->title,ENT_QUOTES));
    return($artist.' - '.$title);
  }

  public function getAsArray()
  {
    foreach($this->fields as $field)
    {
      $data[$field] = $this->$field;
    }
    //print_r($data);
    return $data;
  }

  public function stream()
  {
    session_write_close();
    header("Content-Type: ".$this->format);
    if(USE_TRANSCODE)
    {
      $path = SND_PATH.$this->path;
      if(OS_IS_WINDOWS)
      {
        $path = strtr($path,'/','\\');
        $path = '"'.$path.'"';// prevent white spaces in path name
      }
      $mp3out = 'lame -b '.TRANSCODE_RATE.' --mp3input '.$path.' -';
      passthru($mp3out);
    }
    else
    {
      header("Content-Length: ".$this->filesize);
      readfile(SND_PATH.$this->path);
    }
  }
  
  public function dl()
  {
    $filename = Tools::cleanFileName(noDiacritics(html_entity_decode($this->artist.'_-_'.$this->title.'.mp3',ENT_QUOTES),false));
    session_write_close();
    header("Content-type: ".$this->format);
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Length: ".$this->filesize);
    header("Content-Disposition: attachment; filename=".$filename);
    readfile(SND_PATH.$this->path);
  }

  public function setTag($tag,$tagValue)
  {
    if(in_array($tag,$this->entity_fields))
    {
      $tagValue = htmlentities(utf8_decode($tagValue),ENT_QUOTES);
      if($this->$tag != $tagValue)
      {
        $this->$tag = $tagValue;
        return($this->update());
      }
      return false;
    }
    else
    {
      if($this->$tag != $tagValue)
      {
        $this->$tag = $tagValue;
        return($this->update());
      }
      return false;
    }
    return false;
  }
  
  public function getTag($tag)
  {
    if(in_array($tag,$this->entity_fields))
    {
      if(empty($this->$tag))
      {
        return 'Unknown';
      }
      return utf8_encode(html_entity_decode($this->$tag));
    }
  }
  
  public function getPath()
  {
		return $this->path;
	}
  
  public function owner()
  {
    return $this->usr_id;
  }
  public function update()
  {
    //session_write_close();
    /**
     *First we try to tag file (this is optional)
     */
    $getID3 = new getID3();
    $getID3->encoding = 'UTF-8';
    $tagwriter = new getid3_writetags();
    $tagwriter->filename = SND_PATH.$this->path;
    $tagwriter->tagformats = array('id3v1', 'id3v2.3');
    //$tagwriter->tagformats = array('id3v1');
    $tagwriter->overwrite_tags = false;
    $tagwriter->tag_encoding   = 'UTF-8';
    $tagwriter->remove_other_tags = false;

    $TagData['title'][]   = utf8_encode(html_entity_decode($this->title,ENT_QUOTES));
    $TagData['artist'][]  = utf8_encode(html_entity_decode($this->artist,ENT_QUOTES));
    $TagData['album'][]   = utf8_encode(html_entity_decode($this->album,ENT_QUOTES));
    $TagData['year'][]    = $this->year;
    $TagData['genre'][]   = utf8_encode(html_entity_decode($this->genre,ENT_QUOTES));
    $TagData['comment'][] = utf8_encode(html_entity_decode($this->comment,ENT_QUOTES));
    $TagData['track'][]   = $this->number;
    $tagwriter->tag_data = $TagData;

    $tagwriter->WriteTags();

    /**
     *Next we try to move the file
     */
    switch($this->format)
    {
      case 'audio/mpeg':
        $ext = '.mp3';
        break;
      default:
        $ext = '.mp3';
        break;
    }
    $clean_artist_name = Tools::cleanFileName(noDiacritics($this->artist));
    $new_path = SND_PATH.$clean_artist_name{0}
                            .'/'
                            .$clean_artist_name
                            .'/'
                            .Tools::cleanFileName(noDiacritics($this->album))
                            .'/'
                            .Tools::cleanFileName(noDiacritics($this->title))
                            .$ext;

    if(SND_PATH.$this->path != $new_path)
    {
      //echo('different path');

      $path_parts = pathinfo($new_path);
      if(is_file($new_path))
      {
        $fileprefix = '1';
        if(sha1_file(SND_PATH.$this->path) == sha1_file($new_path))// if file already exists...
        {
          return false;//... do nothing.
        }
        else
        {
          while(is_file($new_path) and $fileprefix<20)// if file toto.mp3 exists, use toto_1.mp3, and so on...
          {
            $new_path = $path_parts['dirname'].'/'.$path_parts['filename'].'_'.$fileprefix.'.'.$path_parts['extension'];
            $fileprefix++;
          }
        }
      }
      
      if(!is_dir($path_parts['dirname']))// create new dir if needed
      {
        mkdir($path_parts['dirname'],0777,TRUE);
      }
      if(Tools::rename_win(SND_PATH.$this->path,$new_path))
      {
        chmod($new_path,0777);
        $this->path = strtr($new_path,array(SND_PATH=>''));
      }

    }

    /**
     *Finally we update DB
     */
    $sql = "UPDATE song SET ";
    foreach($this->fields as $field)
    {
      $update[]=$field."='".sqlite_escape_string($this->$field)."'";
    }
    $sql.=implode(',',$update);
    $sql.=" WHERE id='".$this->id."'";
    //echo($sql);
    $dbh = new dbSql();
    $res = $dbh->exec($sql);
  }

  public function form()
  {
    $html.='<form method="post" action="#" onsubmit="submitId3();return false;">
    <fieldset>
      <legend>ID3</legend>
      <input type="hidden" name="id3SongId" id="id3SongId" value="'.$this->id.'"/>
      <input value="'.utf8_encode(html_entity_decode($this->artist,ENT_QUOTES)).'" type="text" id="id3Artist" name="id3Artist"/>&nbsp;<label>'.STR_UI_ARTIST.'</label><br/>
      <input value="'.utf8_encode(html_entity_decode($this->title,ENT_QUOTES)).'" type="text" id="id3Title" name="id3Title"/>&nbsp;<label>'.STR_UI_TITLE.'</label><br/>
      <input value="'.utf8_encode(html_entity_decode($this->album,ENT_QUOTES)).'" type="text" id="id3Album" name="id3Album"/>&nbsp;<label>'.STR_UI_ALBUM.'</label><br/>
      <input value="'.utf8_encode(html_entity_decode($this->genre,ENT_QUOTES)).'" type="text" id="id3Genre" name="id3Genre"/>&nbsp;<label>'.STR_UI_GENRE.'</label><br/>
      <textarea rows="10" style="width:100%;" cols="40" id="id3Comment" name="id3Comment">'.utf8_encode(html_entity_decode($this->comment,ENT_QUOTES)).'</textarea>&nbsp;<label>'.STR_UI_COMMENT.'</label><br/>
      <input type="text" maxlength="4" name="id3Year" id="id3Year" value="'.$this->year.'"/>&nbsp;<label>'.STR_UI_YEAR.'</label><br/>
      <input type="text" maxlength="4" name="id3Number" id="id3Number" value="'.$this->number.'"/>&nbsp;<label>'.STR_UI_TRACK_NUMBER.'</label><br/>
      <input type="submit" value="'.STR_UI_OK.'"/>
    </fieldset>
    </form>
    ';
    return $html;
  }

  public function delete()
  {
    if(unlink(SND_PATH.$this->path))
    {
      $sql = "DELETE FROM song WHERE id='".$this->id."'";
      $dbh = new dbSql();
      $res = $dbh->exec($sql);
    }
  }

  public function create()
  {
    //create
  }

  public static function getBestTag($tag,$all_infos)//choose between id3v1 and id3v2
  {
    if($all_infos['mime_type'] != 'audio/mpeg')//no vorbis support for now
    {
      return false;
    }
    if(empty($all_infos['tags']['id3v2'][$tag]))
    {
      $i=0;
      while($i<count($all_infos['tags']['id3v1'][$tag]))
      {
        $letag.=$all_infos['tags']['id3v1'][$tag][$i];
        $i++;
      }
      return $letag;
    }
    else
    {
      if($tag=="genre")
      {
        $letag=$all_infos['tags']['id3v2'][$tag][0];
      }
      else
      {
        $i=0;
        while($i<count($all_infos['tags']['id3v2'][$tag]))
        {
          $letag.=$all_infos['tags']['id3v2'][$tag][$i];
          $i++;
        }
      }
      return $letag;
    }
  }
} 
?>
